﻿using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using EssIL;

namespace EssILUnitTest
{
    [TestClass]
    public class FlagTypeTest
    {
        [TestMethod]
        public void EnumType()
        {
            //Assert.IsFalse(true);
            Assert.AreEqual(false, ConsoleModifiers.Alt.TestFlag(ConsoleModifiers.Control));
            Assert.AreEqual(true, (ConsoleModifiers.Control | ConsoleModifiers.Alt).TestFlag(ConsoleModifiers.Control));
            Assert.AreEqual(null, ConsoleModifiers.Control.TestFlag(ConsoleModifiers.Alt | ConsoleModifiers.Control));

        }

        [TestMethod]
        public void Int64Flag()
        {
            Assert.IsTrue((0L).HasFlag(0));
            Assert.IsFalse((0L).HasFlag(0x100000000L));

            Assert.AreEqual(true, (0L).TestFlag(0));
            Assert.AreEqual(false, (0L).TestFlag(0x100000000L));

            Assert.AreEqual(true, (0x100000000L).TestFlag(0));
            Assert.AreEqual(true, (0x100000000L).TestFlag(0x100000000L));
            Assert.AreEqual(true, (0x100000001L).TestFlag(0x100000000L));
            Assert.AreEqual(null, (0x100000000L).TestFlag(0x100000001L));
        }

        [TestMethod]
        public void UInt64Flag()
        {
            Assert.IsTrue((0UL).HasFlag(0));
            Assert.IsFalse((0UL).HasFlag(0x100000000L));

            Assert.AreEqual(true, (0UL).TestFlag(0));
            Assert.AreEqual(false, (0UL).TestFlag(0x100000000UL));

            Assert.AreEqual(true, (0x100000000UL).TestFlag(0));
            Assert.AreEqual(true, (0x100000000UL).TestFlag(0x100000000UL));
            Assert.AreEqual(true, (0x100000001UL).TestFlag(0x100000000UL));
            Assert.AreEqual(null, (0x100000000UL).TestFlag(0x100000001UL));
        }

        [TestMethod]
        public void Int32Flag()
        {
            Assert.IsTrue((0).HasFlag(0));
            Assert.IsFalse((0).HasFlag(0x10000000));

            Assert.AreEqual(true, (0).TestFlag(0));
            Assert.AreEqual(false, (0).TestFlag(0x10000001));

            Assert.AreEqual(true, (0x10000000).TestFlag(0));
            Assert.AreEqual(true, (0x10000000).TestFlag(0x10000000));
            Assert.AreEqual(true, (0x10000001).TestFlag(0x10000000));
            Assert.AreEqual(null, (0x10000000).TestFlag(0x10000001));
        }

        [TestMethod]
        public void UInt32Flag()
        {
            Assert.IsTrue((0U).HasFlag(0));
            Assert.IsFalse((0U).HasFlag(0x10000000));

            Assert.AreEqual(true, (0U).TestFlag(0));
            Assert.AreEqual(false, (0U).TestFlag(0x10000000U));

            Assert.AreEqual(true, (0x10000000U).TestFlag(0));
            Assert.AreEqual(true, (0x10000000U).TestFlag(0x10000000U));
            Assert.AreEqual(true, (0x10000001U).TestFlag(0x10000000U));
            Assert.AreEqual(null, (0x10000000U).TestFlag(0x10000001U));
        }

        [TestMethod]
        public void Int16Flag()
        {
            Assert.IsTrue(((short)0).HasFlag(0));
            Assert.IsFalse(((short)0).HasFlag(0x1000));

            Assert.AreEqual(true, ((short)0).TestFlag((short)0));
            Assert.AreEqual(false, ((short)0).TestFlag((short)0x1001));

            Assert.AreEqual(true, ((short)0x1000).TestFlag((short)0));
            Assert.AreEqual(true, ((short)0x1000).TestFlag((short)0x1000));
            Assert.AreEqual(true, ((short)0x1001).TestFlag((short)0x1000));
            Assert.AreEqual(null, ((short)0x1000).TestFlag((short)0x1001));
        }

        [TestMethod]
        public void UInt16Flag()
        {
            Assert.IsTrue(((ushort)0).HasFlag(0));
            Assert.IsFalse(((ushort)0).HasFlag(0x1000));

            Assert.AreEqual(true, ((ushort)0).TestFlag((ushort)0));
            Assert.AreEqual(false, ((ushort)0).TestFlag((ushort)0x1001));

            Assert.AreEqual(true, ((ushort)0x1000).TestFlag((ushort)0));
            Assert.AreEqual(true, ((ushort)0x1000).TestFlag((ushort)0x1000));
            Assert.AreEqual(true, ((ushort)0x1001).TestFlag((ushort)0x1000));
            Assert.AreEqual(null, ((ushort)0x1000).TestFlag((ushort)0x1001));
        }

        [TestMethod]
        public void UInt8Flag()
        {
            Assert.IsTrue(((byte)0).HasFlag(0));
            Assert.IsFalse(((byte)0).HasFlag(0x10));

            Assert.AreEqual(true, ((byte)0).TestFlag((byte)0));
            Assert.AreEqual(false, ((byte)0).TestFlag((byte)0x11));

            Assert.AreEqual(true, ((byte)0x10).TestFlag((byte)0));
            Assert.AreEqual(true, ((byte)0x10).TestFlag((byte)0x10));
            Assert.AreEqual(true, ((byte)0x11).TestFlag((byte)0x10));
            Assert.AreEqual(null, ((byte)0x10).TestFlag((byte)0x11));
        }

        [TestMethod]
        public void Int8Flag()
        {
            Assert.IsTrue(((sbyte)0).HasFlag(0));
            Assert.IsFalse(((sbyte)0).HasFlag(0x10));

            Assert.AreEqual(true, ((sbyte)0).TestFlag((sbyte)0));
            Assert.AreEqual(false, ((sbyte)0).TestFlag((sbyte)0x11));

            Assert.AreEqual(true, ((sbyte)0x10).TestFlag((sbyte)0));
            Assert.AreEqual(true, ((sbyte)0x10).TestFlag((sbyte)0x10));
            Assert.AreEqual(true, ((sbyte)0x11).TestFlag((sbyte)0x10));
            Assert.AreEqual(null, ((sbyte)0x10).TestFlag((sbyte)0x11));
        }

        enum LongEnum : long
        {
            Zero,
            L4G = 0x100000000L,
            L4G1 = 0x100000001L,
        }

        [TestMethod]
        public void LongEnumTest()
        {
            Assert.IsTrue((LongEnum.Zero).Has(LongEnum.Zero));
            Assert.IsFalse((LongEnum.Zero).Has(LongEnum.L4G));

            Assert.AreEqual(true, LongEnum.Zero.TestFlag(LongEnum.Zero));
            Assert.AreEqual(false, LongEnum.Zero.TestFlag(LongEnum.L4G));

            Assert.AreEqual(true, LongEnum.L4G.TestFlag(LongEnum.Zero));
            Assert.AreEqual(true, LongEnum.L4G.TestFlag(LongEnum.L4G));
            Assert.AreEqual(true, LongEnum.L4G1.TestFlag(LongEnum.L4G));
            Assert.AreEqual(null, LongEnum.L4G.TestFlag(LongEnum.L4G1));
        }

        struct LongStruct
        {
            public long value__;
        }

        [TestMethod]
        public void LongStructHas()
        {
            //Assert.IsTrue(FlagTypeExtensions.HasFlagUnchecked(new LongStruct(), new LongStruct()));
            //try
            //{
            //    Assert.IsFalse(FlagTypeExtensions.HasFlagUnchecked(new LongStruct(), new LongStruct { value__ = 0x10000000 }));
            //}
            //catch (AssertFailedException) { return; }
            //Assert.Fail();
        }
    }
}

